﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Collections.ObjectModel;
using Curling.CurlingServer;
using Microsoft.Phone.Info;
using System.ServiceModel;
using System.Windows.Threading;
using System.Diagnostics;
using System.IO.IsolatedStorage;
using Microsoft.Devices;

namespace Curling
{
    public partial class OptionsPage : PhoneApplicationPage
    {
        readonly IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

        bool GoBack = false;

        //bool StatusOnline = false;
        bool SupressRequests;

        CurlingServiceClient CurlingService;

        DispatcherTimer UpdateTimer;
        DispatcherTimer OneSecondTimer;

        PlayerProfile playerProfile;

        TimeSpan? LastVisitorInterval = null;
        DateTime ServerTime;

        //bool WaitForResponse;

        public OptionsPage()
        {
            InitializeComponent();

            FadeOut.Completed += new EventHandler(FadeOut_Completed);
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            FadeIn.Begin();

            LoadingBar.IsIndeterminate = true;
        }

        private void PhoneApplicationPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            UpdateTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(2.0) };
            UpdateTimer.Tick += new EventHandler(UpdateTimer_Tick);

            OneSecondTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1.0) };
            OneSecondTimer.Tick += new EventHandler(OneSecondTimer_Tick);

            playerProfile = new PlayerProfile() { ID = App.UserID, Name = (string)PhoneApplicationService.Current.State["Player1Name"], Location = (string)settings["Location"] };

            CurlingService = new CurlingServiceClient();

            CurlingService.SetStatusOnlineCompleted += new EventHandler<SetStatusOnlineCompletedEventArgs>(CurlingService_SetStatusOnlineCompleted);
            CurlingService.SetStatusOnlineAsync(playerProfile, App.AppVersion);

            CurlingService.CheckRequestsCompleted += new EventHandler<CheckRequestsCompletedEventArgs>(CurlingService_CheckRequestsCompleted);
            CurlingService.GetUsersOnlineCompleted += new EventHandler<GetUsersOnlineCompletedEventArgs>(CurlingService_GetUsersOnlineCompleted);
            CurlingService.GetLastVisitorIntervalCompleted += new EventHandler<GetLastVisitorIntervalCompletedEventArgs>(CurlingService_GetLastVisitorIntervalCompleted);
            CurlingService.GetAlreadyPlayingCountCompleted += new EventHandler<GetAlreadyPlayingCountCompletedEventArgs>(CurlingService_GetAlreadyPlayingCountCompleted);
            CurlingService.SetStatusOfflineCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(CurlingService_SetStatusOfflineCompleted);
            CurlingService.ChooseOpponentCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(CurlingService_ChooseOpponentCompleted);
        }

        void CurlingService_CheckRequestsCompleted(object sender, CheckRequestsCompletedEventArgs e)
        {
            if (e.Error == null && !SupressRequests)
            {
                PlayerProfile playerProfile = e.Result;

                if (playerProfile != null)
                {
                    if (MessageBox.Show(String.Format("I want to start a game with you. Press OK to accept. Press Cancel to reject.", playerProfile.Name), playerProfile.Name + ":", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        CurlingService.ProcessRequestAsync(App.AuthToken, playerProfile.ID, true);

                        PhoneApplicationService.Current.State["Opponent"] = playerProfile;
                        PhoneApplicationService.Current.State["CurlingService"] = CurlingService;
                        PhoneApplicationService.Current.State["Accepted"] = true;

                        Close(null, false);
                    }
                    else
                    {
                        CurlingService.ProcessRequestAsync(App.AuthToken, playerProfile.ID, false);
                    }
                }
            }
        }

        void CurlingService_GetUsersOnlineCompleted(object sender, GetUsersOnlineCompletedEventArgs e)
        {
            if (!GoBack)
            {
                if (e.Error == null)
                {
                    UpdateTimer.Start();

                    ObservableCollection<PlayerProfile> Players = e.Result;

                    if (Players != null)
                    {
                        if (Players.Count > 0)
                        {
                            if (Players[0] != null)
                            {
                                if (MessageText.Text.StartsWith("Last visitor")) // Developer version only
                                {
                                    VibrateController.Default.Start(TimeSpan.FromMilliseconds(2000));
                                }

                                OnlinePlayersList.ItemsSource = Players;

                                if (MessageText.Visibility == System.Windows.Visibility.Visible)
                                {
                                    MessageText.Visibility = System.Windows.Visibility.Collapsed;
                                }
                            }
                            else
                            { 
                                // Nothing changed
                            }
                        }
                        else
                        {
                            OnlinePlayersList.ItemsSource = null;
                            CurlingService.GetAlreadyPlayingCountAsync(App.AuthToken);
                        }
                    }
                    else
                    {
                        UpdateTimer.Stop();
                        CurlingService.SetStatusOnlineAsync(playerProfile, App.AppVersion);
                    }
                }
                else
                {
                    if (MessageBox.Show("Connection with a server is lost. Try one more time?", "Network error", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        //UpdateTimer.Stop();
                        OneSecondTimer.Stop();
                        CurlingService.SetStatusOnlineAsync(playerProfile, App.AppVersion);
                    }
                }
            }
        }

        void CurlingService_GetAlreadyPlayingCountCompleted(object sender, GetAlreadyPlayingCountCompletedEventArgs e)
        {
            if (!GoBack)
            {
                if (e.Error == null)
                {
                    int AlreadyPlaying = (int)e.Result;

                    if (AlreadyPlaying > 0)
                    {
                        MessageText.Text = String.Format("Already playing: {0}. Wait a moment...", AlreadyPlaying);
                        MessageText.Visibility = System.Windows.Visibility.Visible;
                    }
                    else
                    {
                        CurlingService.GetLastVisitorIntervalAsync(App.AuthToken);
                    }
                }
                else
                {
                    if (MessageBox.Show("Cannot establish connection with a server. Try one more time?", "Network error", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        UpdateTimer.Stop();
                        OneSecondTimer.Stop();
                        CurlingService.SetStatusOnlineAsync(playerProfile, App.AppVersion);
                    }
                }
            }
        }

        void CurlingService_GetLastVisitorIntervalCompleted(object sender, GetLastVisitorIntervalCompletedEventArgs e)
        {
            if (!GoBack)
            {
                if (e.Error == null)
                {
                    LastVisitorInterval = e.Result;
                    ServerTime = DateTime.Now;

                    MessageText.Text = String.Format("Last visitor: {0}", TimeAgo(LastVisitorInterval));
                    MessageText.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    if (MessageBox.Show("Cannot establish connection with a server. Try one more time?", "Network error", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        UpdateTimer.Stop();
                        OneSecondTimer.Stop();
                        CurlingService.SetStatusOnlineAsync(playerProfile, App.AppVersion);
                    }
                }
            }
        }

        void UpdateTimer_Tick(object sender, EventArgs e)
        {
            UpdateTimer.Stop();

            if (CurlingService != null)
            {
                CurlingService.GetUsersOnlineAsync(App.AuthToken, true);
                CurlingService.CheckRequestsAsync(App.AuthToken);
            }
        }

        void CurlingService_SetStatusOnlineCompleted(object sender, SetStatusOnlineCompletedEventArgs e)
        {
            if (!GoBack)
            {
                LoadingBar.IsIndeterminate = false;

                if (e.Error == null)
                {
                    if (e.Result.Length == Guid.Empty.ToString().Length)
                    {
                        App.AuthToken = e.Result;

                        CurlingService.GetUsersOnlineAsync(App.AuthToken, false);
                        //StatusOnline = true;

                        UpdateTimer.Start();
                        OneSecondTimer.Start();
                    }
                    else
                    {
                        MessageBox.Show(e.Result);
                    }
                }
                else
                {
                    if (MessageBox.Show("Cannot establish connection with a server. Try one more time?", "Network error", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        CurlingService.SetStatusOnlineAsync(playerProfile, App.AppVersion);
                    }
                }
            }
        }

        void CurlingService_SetStatusOfflineCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
            {
            }
            //StatusOnline = false;
        }

        private void SelectPlayerButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Button SelectPlayerButton = (Button)sender;
            
            DoubleAnimation doubleAnimation = new DoubleAnimation() { From = 0.0, To = 50.0, Duration = new Duration(TimeSpan.FromSeconds(0.2)) };
            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(doubleAnimation);

            Storyboard.SetTarget(doubleAnimation, SelectPlayerButton.RenderTransform);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(TranslateX)"));
            storyboard.Begin();

            PlayerProfile Opponent = new PlayerProfile()
            {
                ID = (string)SelectPlayerButton.Tag,
                Name = ((SelectPlayerButton.Content as Grid).Children[0] as TextBlock).Text,
                Location = ((SelectPlayerButton.Content as Grid).Children[3] as TextBlock).Text
            };
            
            PhoneApplicationService.Current.State["Opponent"] = Opponent;

            SupressRequests = true;

            CurlingService.ChooseOpponentAsync(App.AuthToken, Opponent.ID);
        }

        void CurlingService_ChooseOpponentCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //WaitForResponse = true;

            PhoneApplicationService.Current.State["CurlingService"] = CurlingService;
            
            Close(null, false);
        }

        private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            PhoneApplicationService.Current.State.Remove("Opponent");

            Close(e, true);
        }

        private void Close(System.ComponentModel.CancelEventArgs e, bool CloseConnection)
        {
            if (!GoBack)
            {
                FadeOut.Begin();
                GoBack = true;

                PhoneApplicationService.Current.State["FromMultiPlayer"] = true;

                if (CurlingService != null && CloseConnection)
                {
                    CurlingService.SetStatusOfflineAsync(App.AuthToken);

                    CurlingService.CloseAsync();
                    UpdateTimer.Stop();
                    OneSecondTimer.Stop();
                    CurlingService = null;
                }
            }

            if (e != null)
                e.Cancel = true;
        }

        void FadeOut_Completed(object sender, EventArgs e)
        {
            if (OneSecondTimer.IsEnabled)
                OneSecondTimer.Stop();

            NavigationService.GoBack();
        }

        void OneSecondTimer_Tick(object sender, EventArgs e)
        {
            if (LastVisitorInterval.HasValue)
            {
                if (MessageText.Visibility == System.Windows.Visibility.Visible)
                    MessageText.Text = String.Format("Last visitor: {0}", TimeAgo(LastVisitorInterval));
            }

            //if (WaitForResponse)
            //{
            //    CurlingService.CheckRequestResultAsync(App.AuthToken, ((PlayerProfile)PhoneApplicationService.Current.State["Opponent"]).ID);
            //}
        }

        private string TimeAgo(TimeSpan? timeStamp)
        {
            if (timeStamp.HasValue)
            {
                int Seconds = (int)DateTime.Now.Subtract(ServerTime).Add(timeStamp.Value).TotalSeconds;
                int Minutes = Seconds / 60;
                int Hours = Minutes / 60;
                int Days = Hours / 24;
                int Month = Days / 30;

                if (Seconds == 1)
                {
                    return Seconds + " second ago";
                }
                if (Seconds < 60)
                {
                    return Seconds + " seconds ago";
                }
                else if (Minutes == 1)
                {
                    return Minutes + " minute ago";
                }
                else if (Minutes < 60)
                {
                    return Minutes + " minutes ago";
                }
                else if (Hours == 1)
                {
                    return Hours + " hour ago";
                }
                else if (Hours < 24)
                {
                    return Hours + " hours ago";
                }
                else if (Days == 1)
                {
                    return Days + " day ago";
                }
                else if (Days < 30)
                {
                    return Days + " days ago";
                }
                else if (Month == 1)
                {
                    return Month + " month ago";
                }
                else
                {
                    return "long ago";
                }
            }
            else
            {
                return "no such information";
            }
        }
    }
}
